home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
dviware
/
dvitovdu32
/
src
/
pascal
/
vt220vdu.p
< prev
next >
Wrap
Text File
|
1991-11-10
|
9KB
|
308 lines
(* VDU routines for a VT220 terminal. *)
#include 'globals.h';
#include 'screenio.h';
#include 'vdu.h';
CONST
SO = CHR(16b);
SI = CHR(17b);
CONST
hpixels = 1; (* horizontal pixels per char position *)
vpixels = 5; (* vertical pixels per char position *)
flag = 7;
hscreenmax = 131; (* max horizontal char coordinate *)
vscreenmax = 23; (* max vertical char coordinate *)
VAR
cursrow, curscol : INTEGER; (* ShowChar remembers cursor location *)
rectcount : INTEGER; (* keeps a count of ShowRectangle calls;
reset in ShowBitmap *)
Bitmap : ARRAY [0..hscreenmax, 0..vscreenmax] OF bytes_or_bits;
(******************************************************************************)
PROCEDURE MoveAbs (row, col : INTEGER);
(* Move cursor to given screen position. *)
BEGIN
WriteChar(ESC); WriteChar('[');
WriteInt(row);
WriteChar(';');
WriteInt(col);
WriteChar('H');
END; (* MoveAbs *)
(******************************************************************************)
PROCEDURE MoveQuick (screenh, screenv : INTEGER);
(* Move cursor to given screen position.
We remember the cursor position (cursrow,curscol) so we can reduce the
output bytes needed to do the next MoveQuick.
StartGraphics resets the position to an undefined state (cursrow = 0).
We also reset when the cursor reaches the right edge (= windowwd) to
avoid possibility of any auto wrap.
*)
VAR amount : INTEGER;
BEGIN
(* first translate DVItoVDU coordinates into actual screen location *)
screenh := screenh + 1;
screenv := screenv + 1;
IF cursrow = screenv THEN BEGIN
(* The cursor is on the same line as in previous MoveQuick call so we only
need to move left or right, and probably just a small amount (if at all).
*)
IF screenh = curscol THEN (* cursor in correct location *)
curscol := curscol + 1 (* cursor will move right when ch written *)
ELSE IF screenh < curscol THEN BEGIN
(* move cursor left *)
amount := curscol - screenh;
WriteChar(ESC); WriteChar('[');
IF amount > 1 THEN BEGIN (* default is 1 col *)
WriteInt(amount);
curscol := curscol - (amount-1);
END;
WriteChar('D');
END
ELSE BEGIN (* move cursor right *)
amount := screenh - curscol;
WriteChar(ESC); WriteChar('[');
IF amount > 1 THEN WriteInt(amount); (* default is 1 col *)
curscol := curscol + (amount+1);
WriteChar('C');
END;
END
ELSE BEGIN (* cursrow undefined or ch on a new line *)
MoveAbs(screenv,screenh);
cursrow := screenv;
curscol := screenh + 1; (* cursor will move right when ch written *)
END;
IF screenh = windowwd THEN (* ch will be written at right edge *)
cursrow := 0; (* so avoid auto wrap next time around *)
END; (* MoveQuick *)
(******************************************************************************)
PROCEDURE ClearBitmap;
(* Clear the Bitmap. *)
VAR h, v : INTEGER;
BEGIN
FOR v := 4 TO vscreenmax DO (* ignore dialogue lines 0..3 *)
FOR h := 0 TO hscreenmax DO
Bitmap[h,v].bits := [];
END; (* ClearBitmap *)
(******************************************************************************)
PROCEDURE ShowBitmap;
(* Display only the flagged characters in the Bitmap. *)
VAR h, v : INTEGER;
BEGIN
WriteChar(SO); (* assume only working over 7 bit comm lines *)
FOR v := 4 TO vscreenmax DO (* ignore dialogue lines *)
FOR h := 0 TO hscreenmax DO
IF flag IN Bitmap[h,v].bits THEN BEGIN (* send flagged character *)
Bitmap[h,v].bits := Bitmap[h,v].bits - [flag]; (* clear flag *)
MoveQuick(h,v);
WriteChar(CHR(ORD(Bitmap[h,v].ch[0]) + 32));
END;
WriteChar(SI); (* assume only working over 7 bit comm lines *)
WriteBuffer;
rectcount := 0;
END; (* ShowBitmap *)
(******************************************************************************)
PROCEDURE StartText;
(* We are about to draw text in dialogue region. *)
BEGIN
ShowBitmap;
END; (* StartText *)
(******************************************************************************)
PROCEDURE MoveToTextLine (line : INTEGER);
(* Move current position to start of given line. *)
BEGIN
MoveAbs(line,1);
END; (* MoveToTextLine *)
(******************************************************************************)
PROCEDURE ClearTextLine (line : INTEGER);
(* Erase given line; note that DVItoVDU does not assume anything about the
current position at the end of this routine.
*)
BEGIN
MoveAbs(line,1);
WriteChar(ESC);
WriteString('[K'); (* erase to end of line *)
END; (* ClearTextLine *)
(******************************************************************************)
PROCEDURE ClearScreen;
BEGIN
WriteChar(ESC);
WriteString('[2J'); (* erase entire screen *)
ClearBitmap; (* reset Bitmap *)
END; (* ClearScreen *)
(******************************************************************************)
PROCEDURE StartGraphics;
(* We are about to draw in window region. *)
BEGIN
rectcount := 0;
cursrow := 0; (* for MoveQuick *)
END; (* StartGraphics *)
(******************************************************************************)
PROCEDURE LoadFont (fontname : string;
fontsize : INTEGER;
mag, hscale, vscale : REAL);
BEGIN
(* only one character size available on VT220s, so do nothing *)
END; (* LoadFont *)
(******************************************************************************)
PROCEDURE ShowChar (screenh, screenv : INTEGER;
ch : CHAR);
(* Show the given Terse character (mapped to ASCII) at the given position. *)
BEGIN
IF rectcount > 0 THEN (* flush Bitmap if ShowRectangle/s are pending *)
ShowBitmap;
MoveQuick(screenh, screenv DIV vpixels);
WriteChar(TeXtoASCII[ch]);
END; (* ShowChar *)
(******************************************************************************)
PROCEDURE ShowRectangle (screenh, screenv, (* top left pixel *)
width, height : INTEGER; (* size of rectangle *)
ch : CHAR); (* black pixel *)
(* Set the given rectangular Bitmap region.
DVItoVDU ensures the top left position is visible and the given
dimensions do not go beyond the window edges.
*)
VAR h, v, vrow : INTEGER;
BEGIN
FOR v := screenv TO screenv + height - 1 DO
FOR h := screenh TO screenh + width - 1 DO BEGIN
(* set bit h,v in Bitmap *)
vrow := v DIV vpixels;
(* include flag so char will be sent *)
Bitmap[h,vrow].bits := Bitmap[h,vrow].bits + [v MOD vpixels, flag];
END;
rectcount := rectcount + 1;
IF rectcount = 400 THEN (* avoid too much of a pause before flushing Bitmap *)
ShowBitmap;
END; (* ShowRectangle *)
(******************************************************************************)
PROCEDURE LoadPixels;
(* Down-load the chunky graphics character set into the VT220. *)
BEGIN
WriteChar(ESC); WriteChar('P');
WriteString('1;1;2;3;2;1{&%C');
WriteString('BBBBBBBB/????????;');
WriteString('KKKKKKKK/????????;');
WriteString('NNNNNNNN/????????;');
WriteString('oooooooo/????????;');
WriteString('rrrrrrrr/????????;');
WriteString('{{{{{{{{/????????;');
WriteString('~~~~~~~~/????????;');
WriteString('????????/BBBBBBBB;');
WriteString('BBBBBBBB/BBBBBBBB;');
WriteString('KKKKKKKK/BBBBBBBB;');
WriteString('NNNNNNNN/BBBBBBBB;');
WriteString('oooooooo/BBBBBBBB;');
WriteString('rrrrrrrr/BBBBBBBB;');
WriteString('{{{{{{{{/BBBBBBBB;');
WriteString('~~~~~~~~/BBBBBBBB;');
WriteString('????????/KKKKKKKK;');
WriteString('BBBBBBBB/KKKKKKKK;');
WriteString('KKKKKKKK/KKKKKKKK;');
WriteString('NNNNNNNN/KKKKKKKK;');
WriteString('oooooooo/KKKKKKKK;');
WriteString('rrrrrrrr/KKKKKKKK;');
WriteString('{{{{{{{{/KKKKKKKK;');
WriteString('~~~~~~~~/KKKKKKKK;');
WriteString('????????/NNNNNNNN;');
WriteString('BBBBBBBB/NNNNNNNN;');
WriteString('KKKKKKKK/NNNNNNNN;');
WriteString('NNNNNNNN/NNNNNNNN;');
WriteString('oooooooo/NNNNNNNN;');
WriteString('rrrrrrrr/NNNNNNNN;');
WriteString('{{{{{{{{/NNNNNNNN;');
WriteString('~~~~~~~~/NNNNNNNN');
WriteChar(ESC); WriteChar(CHR(134b)); (* ESC \ *)
WriteChar(ESC); WriteString(')&%C'); (* set as G1 character set *)
END; (* LoadPixels *)
(******************************************************************************)
PROCEDURE ResetVDU;
(* We don't do a hardware reset, but leave VDU in 80 column mode. *)
BEGIN
WriteChar(ESC); WriteString('[?3l'); (* 80 column mode *)
END; (* ResetVDU *)
(******************************************************************************)
PROCEDURE InitVDU;
(* The dialogue region is the top 4 lines.
The window region is the remaining area of the screen
(the bottom 20 rows in Bitmap).
*)
BEGIN
DVIstatusl := 1;
windowstatusl := 2;
messagel := 3;
commandl := 4;
bottoml := vscreenmax + 1;
(* DVItoVDU's coordinate scheme is the same as the VT220 scheme. *)
windowh := 0;
windowv := 4 * vpixels; (* = height of 4 dialogue lines *)
windowwd := (hscreenmax + 1) * hpixels;
windowht := (vscreenmax + 1) * vpixels - windowv;
LoadPixels;
WriteChar(ESC); WriteString('[?3h'); (* 132 column mode *)
END; (* InitVDU *)